package com.jqq.api.statement;
import com.mysql.cj.jdbc.Driver;

import java.sql.*;
import java.util.Properties;
import java.util.Scanner;

/**
 * @author 姬倩倩
 * @version 1.0
 * 模拟用户登录
 * TODO：
 *     1.明确jdbc的使用流程 和 详细讲解内部设计的api方法
 *     2.发现问题，引出prepareStatement
 *
 *     输入账号和密码
 *     进行数据库信息查询(t_user)
 *     反馈登陆成功还是登陆失败
 *
 *     1.键盘输入事件，收集账号和密码信息
 *     2.注册驱动
 *     3.获取连接
 *     4.创建statement
 *     5.发送查询SQL语句，并返回结果集
 *     6.结果判断，显示登录成功/失败
 *     7.关闭资源
 */
public class StatementUserLoginPart {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //1.获取用户输入信息
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入账号：");
        String account = scanner.nextLine();
        System.out.println("请输入密码：");
        String password = scanner.nextLine();

        //2.注册驱动
        /**
         * 问题：会注册两次驱动
         *  1. DriverManager.registerDriver()
         *  2.Driver.static{ DriverManager.registerDriver()}
         *  解决：只想注册一次驱动
         *      只触发静态代码块即可！Driver
         *  触发静态代码块：
         *      类加载机制：类加载的时候，会触发静态代码块
         *      加载[class文件 -> jvm虚拟机的class对象]
         *      连接[验证(检查文件类型) -> 准备(静态变量默认值) -> 解析(触发静态代码块)]
         *      初始化[给静态属性赋真实值]
         *  触发类加载：
         *      1.new 关键字
         *      2.调用静态方法
         *      3.调用静态属性
         *      4.接口 1.8 default默认实现
         *      5.反射,Class.forName
         *      6.初始化一个子类
         *      7.程序的入口main
         */
        //方案1
        //DriverManager.registerDriver(new Driver());
        //方案2
        //new Driver();

        //反射
        //字符串可以提取到外部的配置文件，方便以后修改数据库驱动的更换
        Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载

        //3.获取数据库连接
        /**
         * getConnection(1, 2, 3)方法，是一个重载方法
         * 允许开发者，用不同的形式传入数据库连接的核心参数
         *
         * 核心属性：
         *      1.数据库软件所在的主机的ip地址：localhost | 127.0.0.1
         *      2.数据库所在主机的端口号：3306
         *      3.连接的具体库：test_q
         *      4.连接的账号：root
         *      5.连接的密码：123456
         *  三个参数
         *  getConnection(String url, //jdbc:[mysql|oracle|..]:ip地址|主机名:端口号/数据库名?key=value
         *                  jdbc:mysql://127.0.0.1:3306/test_q
         *                  省略版本(本地主机+默认端口号)：jdbc:mysql///test_q
         *              String user,
         *              String password)
         *  两个参数
         *  String url:同上
         *  Properties info:存储账号和密码
         *      类似于Map key=value都是字符串形式
         *      key user：账号信息
         *      key password：密码信息
         *  一个参数
         *  String url：数据库ip,端口号，具体的数据库 可选信息(账号密码)
         *              jdbc:数据库软件名://ip:port/数据库?key=value&key=value
         *              jdbc:mysql://127.0.0.1:3306/test_q?user=root&password=123456
         */
        Connection connection = DriverManager.getConnection("jdbc:mysql:///test_q", "root", "123456");

        Properties info = new Properties();
        info.put("user", "root");
        info.put("password", "123456");
//        Connection connection1 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_q", info);
//
//        Connection connection2 = DriverManager.getConnection("jdbc:mysql:///test_q?user=root&password=123456");

        //4.创建发送SQL语句的statement对象
        Statement statement = connection.createStatement();

        //5.发送SQL语句(1.编写SQL语句 2.发送SQL语句)
        String sql = "select * from t_user where account='"+account+"'and password ='"+password+"';";
        /**
         * SQL语句分类：DDL(容器创建，修改，删除),DML(插入，修改，删除),DQL(查询),DCL(权限控制),TPL(事务控制语言)
         * 参数：sql 非DQL
         * 返回：int
         *      情况1：DML 返回影响的行数，例如：删除了3行数据 return 3
         *      情况2：非DML return 0
         *  int row = executeUpdate(sql)
         *
         *  参数：sql DQL
         *  返回：resultSet结果封装对象
         *  ResultSet resultSet = executeUpdate(sql);
         */
        //int i = statement.executeUpdate(sql);
        ResultSet resultSet = statement.executeQuery(sql);

        //6.查询结果集解析：resultSet
        /**
         *查询结果封装成resultSet,内部一定也是有行和有列的
         * resultSet -> 逐行获取数据 -> 行的列数据
         *
         * 1.移动游标指定获取数据行
         *  游标默认指的是第一行数据之前
         *  调用next()向后移动
         *  使用while(next)获取多行数据
         * 2.获取指定行的列数据
         *  String get类型(String columnLabel | int columnIndex);
         *  columnLabel：列名 如果有别名 写别名
         *  columnIndex：列的下角标获取 从左到右 从1开始
         */
//        while (resultSet.next()){
//            //指定当前行了
//            int id = resultSet.getInt(1);
//            String account1 = resultSet.getString("account");
//            String password1 = resultSet.getString("password");
//            String nickname = resultSet.getString("nickname");
//            System.out.println(
//                    id+"--"+account1+"--"+password1+ "--"+"nickname="+ nickname
//            );
//        }
        //移动一次光标，只要有数据，就代表登录成功
        if(resultSet.next()){
            System.out.println("登录成功！");
        } else{
            System.out.println("登录失败！");
        }
        //7.关闭资源
        resultSet.close();
        statement.close();
        connection.close();

    }
}
